/*
 * FreeModbus Libary: BSD Socket Library Port
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id$
 */

 /**********************************************************
 *	Linux TCP support.
 *	Based on Walter's project. 
 *	Modified by Steven Guo <gotop167@163.com>
 ***********************************************************/

#ifndef _PORT_H
#define _PORT_H


#include <assert.h>
#include "socket.h"
#include "w5500.h"

#define	INLINE
#define PR_BEGIN_EXTERN_C			extern "C" {
#define	PR_END_EXTERN_C				}

#ifdef __cplusplus
PR_BEGIN_EXTERN_C
#endif
/* ----------------------- Defines ------------------------------------------*/
 
#define MB_PORT_HAS_CLOSE	1
#ifndef TRUE
#define TRUE            1
#endif
#ifndef FALSE
#define FALSE           0
#endif
/* ----------------------- Type definitions ---------------------------------*/
// typedef int     SOCKET;

#define SOCKET_ERROR (-1)
#define INVALID_SOCKET 0xff  //(~0)
typedef char    BOOL;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
typedef char    CHAR;
typedef unsigned short USHORT;
typedef short   SHORT;

typedef unsigned long ULONG;
typedef long    LONG;
typedef enum
{
    MB_LOG_DEBUG,
    MB_LOG_INFO,
    MB_LOG_WARN,
    MB_LOG_ERROR
} eMBPortLogLevel;

/* ----------------------- Function prototypes ------------------------------*/

void            TcpvMBPortLog( eMBPortLogLevel eLevel, const CHAR * szModule, const CHAR * szFmt,
                               ... );



//===================port_Start============================
#define  _ModbusUart1_  1
#define  _ModbusUart2_	0

#if (_ModbusUart1_ !=0)
extern TIM_HandleTypeDef htim7;
#define TIMER_ModbusUart1_Modbus_IRQn TIM7_LPTIM2_IRQn
#define	TIMER_ModbusUart1_Modbus_Handle  htim7
#endif

#if (_ModbusUart2_ !=0)
extern TIM_HandleTypeDef htim3;
#define TIMER_R485_Chanel_LPUART1_Modbus_IRQn TIM3_IRQn
#define	Timer_R485_Chanel_LPUART1_Handle  htim3
#endif

//===================port_End============================


/* ----------------------- Defines ------------------------------------------*/
 
#define PR_BEGIN_EXTERN_C           extern "C" {
#define	PR_END_EXTERN_C             }
#ifdef _freertosuse_
#define ENTER_CRITICAL_SECTION( )   taskENTER_CRITICAL()	//vMBPortEnterCritical()
#define EXIT_CRITICAL_SECTION( )   	taskEXIT_CRITICAL()	// vMBPortExitCritical()
#else
#define ENTER_CRITICAL_SECTION( )	{} //vMBPortEnterCritical()
#define EXIT_CRITICAL_SECTION( )	{} //vMBPortExitCritical()
#endif

#define assert( x )

typedef char BOOL;

typedef unsigned char UCHAR;
typedef char CHAR;

typedef unsigned short USHORT;
typedef short SHORT;

typedef unsigned long ULONG;
typedef long LONG;

#ifndef TRUE
#define TRUE	1
#endif

#ifndef FALSE
#define FALSE	0
#endif

//	
#define	_RegExchangeNo(stucttype,unit)	((unsigned int)&(((struct stucttype *)0)->unit)/sizeof(short))
#define	_ModRegLen(stucttype,unit)	((unsigned int)sizeof(((struct stucttype *)0)->unit))
  

#define MB_PORT_HAS_CLOSE	                    1
#define MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS   0

/* ----------------------- Prototypes ---------------------------------------*/
void vMBPortEnterCritical (void);
void vMBPortExitCritical (void);

// Modbus??
enum ENUMMODBUSSTATE
{
  _modbusstate_null_ = 0,
  _modbusstate_recewait_,
  _modbusstate_recetimeout_,
  _modbusstate_sendwait_,
  _modbusstate_sendover_,
  _modbusstate_end_,
};


enum ENUMMODBUSUART
{
  _modbusuart_start_ = 0,
  _modbusuart1_ = _modbusuart_start_,
	_modbusuart_end_,
	_modbusuart2_  ,  
  _modbusuart_err_ 
};

#define	_IsMBChanel_Err(chanel)		( chanel >=_modbusuart_end_)
struct STPORTDCHANEL
{
  struct STUARTUNIT *stp;
  TIM_HandleTypeDef *htim;
  IRQn_Type enIrq;
  unsigned long lTimeSet;
  enum ENUMMODBUSSTATE enModbusAppState;
};

struct STPORTDESCRIPTION
{
  enum ENUMMODBUSUART enWorkChanel;
  struct STPORTDCHANEL stprotdchanel[_modbusuart_end_];
};

extern  struct STPORTDESCRIPTION MB_Port_StDataDescription;
#define _enWorkChanel  MB_Port_StDataDescription.enWorkChanel
	
#define 		_ModBusAppState_Con(chanel , value)		{MB_Port_StDataDescription.stprotdchanel[chanel].enModbusAppState=value;}
#define 		_ModBusAppState_init(chanel)  _ModBusAppState_Con(chanel , _modbusstate_recewait_)
#define 		_ModBusAppState_Get(chanel)  (MB_Port_StDataDescription.stprotdchanel[chanel].enModbusAppState)

void MB_SendOver_EventFun (enum ENUMMODBUSUART   cUnitno);
void MB_Rece_Idel_EventFun( UART_HandleTypeDef * huart);

#define	_MB_WorkChanel_Con(chanel)			{ MB_Port_StDataDescription.enWorkChanel = chanel;}

enum ENUMMODBUSUART MB_Port_Des_GetHuart (UART_HandleTypeDef * huart);
enum ENUMMODBUSUART MB_Port_Des_GetHtim (TIM_HandleTypeDef * him);

#define	_MBChaneSendBuf()	(MB_Port_StDataDescription.stprotdchanel[MB_Port_StDataDescription.enWorkChanel].stp->sTxBuf)
#define	_MBChaneSendBufLen()	(MB_Port_StDataDescription.stprotdchanel[MB_Port_StDataDescription.enWorkChanel].stp->iTxBufLen)

#define	_MBChenalIoGet()	MB_Port_StDataDescription.stprotdchanel[MB_Port_StDataDescription.enWorkChanel].stp->unitp
#define	_MBChenalGet(enNo)	MB_Port_StDataDescription.stprotdchanel[enNo].stp

#define	_MBTChenalTimeIrqGet(enNo)	MB_Port_StDataDescription.stprotdchanel[enNo].enIrq
#define	_MBTChenalTimeGet(enNo)	MB_Port_StDataDescription.stprotdchanel[enNo].htim

#define	_MBChenalDmaPrev(enNo)	(MB_Port_StDataDescription.stprotdchanel[enNo].stp->stDmap->lPrevData)
#define	_MBChenalDmaCurr(enNo)	(MB_Port_StDataDescription.stprotdchanel[enNo].stp->stDmap->lCurrData)

#define	_MBchanelReceLenp(chanel)	(MB_Port_StDataDescription.stprotdchanel[chanel].stp->iRecelen)
#define	_MBchanelReceLen(chanel)	*(_MBchanelReceLenp(chanel))
#define	_MBchaneReceLen_Con(chanel,value)	{_MBchanelReceLen(chanel)=value;}
#define	_MBchaneReceLen_Clr(chanel)	_UsartReceLen_Con(chanel,0)
#define	_MBChenalTimesetIoGet(enNo)	MB_Port_StDataDescription.stprotdchanel[enNo].lTimeSet
#define	_MBChenalTimesetGet()	MB_Port_StDataDescription.stprotdchanel[MB_Port_StDataDescription.enWorkChanel].lTimeSet

void MB_Init (void);
void
vMBPortSerialEnableISR( enum ENUMMODBUSUART enNo ,BOOL xRxEnable, BOOL xTxEnable );
BOOL  Timer_contimoutsetISR( enum ENUMMODBUSUART enNo ,USHORT usTim1Timerout50us ) ;

#ifdef __cplusplus
PR_END_EXTERN_C
#endif
#endif
